#include "stdint.h"
#include "stdio.h"
#include "string.h"
#include "esp32c2_it.h"
#include "DevicesDelay.h"
#include "DevicesQueue.h"
#include "DevicesUart.h"


void vUart0Init(void)
{
    uart_config_t uart_config = {0};
    uart_intr_config_t intr_conf = {0};

    /* 配置参数 */
    uart_config.baud_rate = 115200;
    uart_config.data_bits = UART_DATA_8_BITS;
    uart_config.parity = UART_PARITY_DISABLE;
    uart_config.stop_bits = UART_STOP_BITS_1;
    uart_config.flow_ctrl = UART_HW_FLOWCTRL_DISABLE;
    uart_config.rx_flow_ctrl_thresh = 122;
    uart_param_config(UART_NUM_0, &uart_config);

    /* 配置中断 */
    intr_conf.intr_enable_mask = UART_RXFIFO_FULL_INT_ENA | UART_RXFIFO_TOUT_INT_ENA;
    intr_conf.rx_timeout_thresh = 10;
    intr_conf.rxfifo_full_thresh = 80;
    uart_intr_config(UART_NUM_0, &intr_conf);

    /* 注册中断 */
    esp_intr_alloc(ETS_UART0_INTR_SOURCE,
                  ESP_INTR_FLAG_LEVEL1,
                  uart_isr,
                  (void *)&UART0,
                  NULL);

    /* 设置引脚 */
    uart_set_pin(UART_NUM_0, GPIO_NUM_20, GPIO_NUM_19, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE);
}

void vUart1Init(void)
{
    uart_config_t uart_config = {0};
    uart_intr_config_t intr_conf = {0};

    /* 配置参数 */
    uart_config.baud_rate = 115200;
    uart_config.data_bits = UART_DATA_8_BITS;
    uart_config.parity = UART_PARITY_DISABLE;
    uart_config.stop_bits = UART_STOP_BITS_1;
    uart_config.flow_ctrl = UART_HW_FLOWCTRL_DISABLE;
    uart_config.rx_flow_ctrl_thresh = 122;
    uart_param_config(UART_NUM_1, &uart_config);

    /* 配置中断 */
    intr_conf.intr_enable_mask = UART_RXFIFO_FULL_INT_ENA | UART_RXFIFO_TOUT_INT_ENA;
    intr_conf.rx_timeout_thresh = 10;
    intr_conf.rxfifo_full_thresh = 80;
    uart_intr_config(UART_NUM_1, &intr_conf);

    /* 注册中断 */
    esp_intr_alloc(ETS_UART1_INTR_SOURCE,
                  ESP_INTR_FLAG_LEVEL2,
                  uart_isr,
                  (void *)&UART1,
                  NULL);

    /* 设置引脚 */
    uart_set_pin(UART_NUM_1, GPIO_NUM_18, GPIO_NUM_10, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE);
}

void vUartBaudrateSet(uart_dev_t *uart, int32_t iBaudrate)
{
    uint32_t sclk_freq;

    uart_get_sclk_freq(UART_SCLK_DEFAULT, &sclk_freq);

    uart_ll_set_baudrate(uart, iBaudrate, sclk_freq);
}

void vUartSendDatas(uart_dev_t *uart, void *pvDatas, int32_t iLength)
{
    uint8_t *pucDatas = pvDatas;

    while(iLength > 0)
    {
        if(uart->status.txfifo_cnt < 128)
        {
            uart->ahb_fifo.val = *pucDatas++;
            --iLength;
        }
    }

    // /* 等待发送完毕 */
    // while((uart_ll_get_intraw_mask(uart) & UART_INTR_TX_DONE) == 0);
}

void vUartSendStrings(uart_dev_t *uart, char *pcStrings)
{
    vUartSendDatas(uart, pcStrings, strlen(pcStrings));
}

int8_t cUartReceiveByte(uart_dev_t *uart, uint8_t *pucByte)
{
    return cUartReceiveDatas(uart, pucByte, 1);
}

int8_t cUartReceiveDatas(uart_dev_t *uart, void *pvDatas, int32_t iLength)
{
    QueueType *ptypeQueue = (uart == &UART0) ? &g_TypeQueueUart0Read : &g_TypeQueueUart1Read;

    if(iLength < 1)
        return 1;

    /* 判断队列内是否有足够的数据 */
    if(iQueueGetLength(ptypeQueue) < iLength)
        return 3;

    /* 从队列内获取数据 */
    if(enumQueuePopDatas(ptypeQueue, pvDatas, iLength) != queueNormal)
        return 4;

    return 0;
}

int32_t iUartReceiveAllDatas(uart_dev_t *uart, void *pvDatas, int32_t iLengthLimit)
{
    QueueType *ptypeQueue = (uart == &UART0) ? &g_TypeQueueUart0Read : &g_TypeQueueUart1Read;
    int32_t iLength = 0;

    if((pvDatas == NULL) || (iLengthLimit < 1))
        return 0;

    /* 读取队列内有效数据的长度 */
    if((iLength = iQueueGetLength(ptypeQueue)) < 1)
        return 0;

    /* 限制读取长度 */
    iLength = iLength > iLengthLimit ? iLengthLimit : iLength;

    /* 从队列内获取数据 */
    if(enumQueuePopDatas(ptypeQueue, pvDatas, iLength) != queueNormal)
        return 0;

    return iLength;
}

int32_t iUartReceiveLengthGet(uart_dev_t *uart)
{
    QueueType *ptypeQueue = (uart == &UART0) ? &g_TypeQueueUart0Read : &g_TypeQueueUart1Read;

    /* 读取队列内有效数据的长度 */
    return iQueueGetLength(ptypeQueue);
}

int8_t cUartReceiveClear(uart_dev_t *uart)
{
    QueueType *ptypeQueue = (uart == &UART0) ? &g_TypeQueueUart0Read : &g_TypeQueueUart1Read;

    /* 设置队列状态为空 */
    return enumQueueClear(ptypeQueue);
}
